package sorting.main;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import sorting.algorithms.HeapSort;
import sorting.algorithms.InsertionSort;
import sorting.algorithms.MergeSort;
import sorting.algorithms.QuickSort;
import sorting.algorithms.SortingAlgorithm;;

public class Main {
	
	public static void main(String[] args){
		List<SortingAlgorithm> algos = new ArrayList<SortingAlgorithm>();
		algos.add(new HeapSort());
		algos.add(new QuickSort());
		algos.add(new MergeSort());
		//algos.add(new InsertionSort());		
		
		//create random list of ints as comparables
		List<Comparable> testList = new ArrayList<Comparable>();
		for (int i = 0; i < 100000; i++){
			testList.add((int) (Math.random()*10000));
		}
		
		List<Comparable> checks = null;
		for (SortingAlgorithm algo : algos){
			long start = System.nanoTime();
			List<Comparable> l = algo.sort(testList);
			//for (Comparable c : l){
			//	System.out.println(c);
			//}
			
			long end = System.nanoTime();
			System.out.println(algo.getName() + " in " + getExecutionTime(start, end));
			if (checks == null){
				checks = l;
				boolean correct = checks.size() == testList.size();
				int i = 1;
				Comparable previous = checks.get(0);
				while (i < checks.size() && correct){
					correct = checks.get(i).compareTo(previous) >= 0;
					i++;
				}
				System.out.println("Checked, correct: " + correct);
			} else {
				boolean correct = checks.size() == l.size();
				int i = 0;
				while (i < checks.size() && correct){
					correct = l.get(i).equals(checks.get(i));
					i++;
				}
				System.out.println("Checked, correct: " + correct);
			}
		}
	}
	
	private static String getExecutionTime( long start, long end )	{
		long time = end - start;
		if ( time > 1000000000 )
			return( "executed in: " + ( time / 10000000 ) / 100.0 + " s"  );
		else if ( time > 1000000 )
			return( "executed in: " + ( time / 10000    ) / 100.0 + " ms" );
		else if ( time > 1000 )
			return( "executed in: " + ( time / 10       ) / 100.0 + " us" );
		else
			return( "executed in: " + ( time            )         + " ns" );
	}

}
